/* $Id:guild.cc $ */
/*
   Copyright (C) 2007 by Jurjen Stellingwerff <jurjen@stwerff.xs4all.nl>
   Part of the Moros Project http://moros.sourceforge.net/

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 3.
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY.

   See the COPYING file for more details.
*/

#define DEBUG_ROUTINE "guild"

#include <sstream>
#include <fstream>
#include "../general/util.h"
#include "../general/log.h"
#include "../general/channel.h"
#include "guild.h"
#include "skill.h"
#include "skill.h"
#include "../general/general.h"

guild::guild() {
    name="";
    description="";
    skills=map<string,class skill_level>();
    deity=0;
    members=map<string,class person>();
    armies=map<string,class army>();
}

// Field : name

const string guild::getName() const { return name; }
void guild::setName(const string v) { name=v; }

// Field : description

const string guild::getDescription() const { return description; }
void guild::setDescription(const string v) { description=v; }

// Field : skills

class skill_level& guild::getSkills(const string v) { return skills[v]; }
map<string,class skill_level>& guild::listSkills() { return skills; }
void guild::setSkills(class skill_level &v) {
    skills[v.getSkill().getName()]=v;
}
void guild::delSkills(const string v) { skills.erase(v); }
const bool guild::isSkills(const string v) const { return skills.count(v)>0; }

// Field : deity

class skill& guild::getDeity() const { if (deity==0) throw nullpointer(); return *deity; }
void guild::setDeity(class skill &v) { deity=&v; }

// Field : members

class person& guild::getMembers(const string v) { return members[v]; }
map<string,class person>& guild::listMembers() { return members; }
void guild::setMembers(class person &v) {
    if (v.getName()=="") throw unnamed();
    members[v.getName()]=v;
}
void guild::delMembers(const string v) { members.erase(v); }
const bool guild::isMembers(const string v) const { return members.count(v)>0; }

// Field : armies

class army& guild::getArmies(const string v) { return armies[v]; }
map<string,class army>& guild::listArmies() { return armies; }
void guild::setArmies(class army &v) {
    if (v.getName()=="") throw unnamed();
    armies[v.getName()]=v;
}
void guild::delArmies(const string v) { armies.erase(v); }
const bool guild::isArmies(const string v) const { return armies.count(v)>0; }

void guild::save(class channel &ch) {
    ch.write("guild", "");
    ch.write("n", getName());
    ch.write("d", getDescription());
    loopGuildSkills(this, s_skills) {
        s_skills->save(ch);
    }
    ch.write("de", getDeity().getName());
    loopGuildMembers(this, s_members) {
        s_members->save(ch);
    }
    loopGuildArmies(this, s_armies) {
        s_armies->save(ch);
    }
}

void guild::load(class channel &ch) {
    if (ch.key=="n" || ch.key=="name") { setName(ch.value); ch.next(); }
    if (ch.key=="d" || ch.key=="description") { setDescription(ch.value); ch.next(); }
    while (ch.key=="skill_level" || ch.key=="skills") {
        ch.next();
        class skill_level rec;
        rec.load(ch);
        setSkills(rec);
    }
    if (ch.key=="de" || ch.key=="deity") {
        if (!skill_repo.isSkill(ch.value)) {
            dbg_state("link unknown skill %s", ch.value.c_str());
            class skill rec;
            rec.setName(ch.value);
            skill_repo.setSkill(rec);
        }
        setDeity(skill_repo.getSkill(ch.value));
        ch.next();
    }
    while (ch.key=="person" || ch.key=="members") {
        ch.next();
        class person rec;
        rec.load(ch);
        setMembers(rec);
    }
    while (ch.key=="army" || ch.key=="armies") {
        ch.next();
        class army rec;
        rec.load(ch);
        setArmies(rec);
    }
}

void guild::xml(ofstream &f, int l, int r) {
    f << ncpy(l, "  ") << "<guild name=\"" << xml_encode(getName()) <<
    "\" description=\"" << xml_encode(getDescription()) <<
    "\">" << endl;
    if (r<2) try {
        getDeity().xml(f,l+1,r+1);
    } catch (nullpointer n) {}
    if (r==0) {
        loopGuildSkills(this, s_skills) {
            s_skills->xml(f,l+1);
        }
        loopGuildMembers(this, s_members) {
            s_members->xml(f,l+1);
        }
        loopGuildArmies(this, s_armies) {
            s_armies->xml(f,l+1);
        }
    }
    f << ncpy(l, "  ") << "</guild>" << endl;
}
